import React, { useEffect, useRef } from 'react';
import moment from 'moment';
import { Form } from 'antd';
import request from '@/utils/request';
import { getDurationFlexible } from '@/utils/utils';
import { getDataSource } from '@/components/Custom/Time/Time';
import { getFormatByUnit, getTimeExtraParam } from '@/pages/Flow/Mine/ApplyPage/utils';
import AutoRenderComponent from '@/pages/WorkFlow/components/FormControls/components/AutoRenderComponent/AutoRenderComponent';

const BusinessTrip = ({ dataSource, form }) => {
    const { getFieldDecorator } = form;
    const { children: list = [] } = dataSource;
    const formRef = useRef(form);

    useEffect(() => {
        const country = 'zh';
        const dateSource = getDataSource(15);
        const nextTime = dateSource.find(newItem => newItem >= moment().format('HH:mm'));
        const endNextTime = moment(moment(nextTime, 'HH:mm').add(60, 'm')).format('HH:mm');
        const unit = 2;

        const { children = [] } = dataSource;

        const [startTime = {}, endTime = {}] = [
            children.find(item => item.formId === 'startTime'),
            children.find(item => item.formId === 'endTime')
        ];

        const setTimeValue = (initialValue, type) => {
            if (initialValue) {
                return initialValue;
            }
            let timeValue = '';
            if (type === 'startTime') {
                timeValue = unit === 3 ? nextTime : '';
            } else if (type === 'endTime') {
                timeValue = unit === 3 ? endNextTime : '';
            }
            return {
                time: '',
                type,
                timeValue,
                dayType: '',
                disabled: startTime.options.disabled,
                unit,
                country
            };
        };

        formRef.current.setFieldsValue({
            startTime: setTimeValue(startTime.initialValue, 'startTime'),
            endTime: setTimeValue(endTime.initialValue, 'endTime')
        });
    }, [dataSource]);

    // 自定义验证规则
    const resolveFormRules = control => {
        const { formId = '', rules = [] } = control;
        switch (formId) {
            case 'startTime': {
                const endTimeName = 'endTime';
                rules[0] = {
                    ...rules[0],
                    validator(_, value, callback) {
                        const endTime = form.getFieldValue(endTimeName);
                        if (!value || !value.time || (value.unit === 2 && !value.dayType)) {
                            callback('请选择开始时间！');
                        } else if (moment(value.time) > moment(endTime.time)) {
                            callback('开始时间不能晚于结束时间！');
                        } else {
                            callback();
                        }

                        form.validateFields([endTimeName]);
                    }
                };

                return rules;
            }
            case 'endTime': {
                const startTimeName = 'startTime';
                rules[0] = {
                    ...rules[0],
                    validator(_, value, callback) {
                        const startTime = form.getFieldValue(startTimeName);
                        if (!value || !value.time || (value.unit === 2 && !value.dayType)) {
                            callback('请选择结束时间！');
                        } else if (moment(value.time) < moment(startTime.time)) {
                            callback('结束时间不能早于开始时间！');
                        } else {
                            callback();
                        }

                        form.validateFields([startTimeName]);
                    }
                };
                return rules;
            }
            case 'duration': {
                rules[0] = {
                    ...rules[0],
                    validator(_, value, callback) {
                        if (value === 0) {
                            callback('时长不能为 0！');
                        } else if (!value) {
                            callback('时长不能为空！');
                        } else {
                            callback();
                        }
                    }
                };

                return rules;
            }
            default:
                return rules;
        }
    };

    // 设置总预算
    const setTotalExpense = fieldsValue => {
        const { hotelExpense, transportExpense, businessTripAllowance, otherExpense } = fieldsValue;
        const totalExpense = [
            Number(hotelExpense) || 0,
            Number(transportExpense) || 0,
            Number(businessTripAllowance) || 0,
            Number(otherExpense) || 0
        ].reduce((total, num) => total + num);
        form.setFieldsValue({ businessTripTotalExpense: Number(totalExpense.toFixed(2)) });
    };

    const concatTime = ({ time, timeValue }) => {
        if (!timeValue) return time;
        return moment(moment(`${time.format('YYYY-MM-DD')} ${timeValue}:00`));
    };

    // 设置时长
    const setDuration = async fieldsValue => {
        const { startTime, endTime } = fieldsValue;

        if (startTime.time && startTime.dayType && endTime.time && endTime.dayType) {
            const s = concatTime(startTime);
            const e = concatTime(endTime);
            if (s.isValid() && e.isValid()) {
                const { country, unit } = startTime;
                // 上午下午类型要加参数
                const extra = getTimeExtraParam(startTime, endTime, unit);
                const postStartTime = getFormatByUnit('startTime', country, 2, startTime.time);
                const postEndTime = getFormatByUnit('endTime', country, 2, endTime.time);
                const currentUser = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : {};

                const result = await request('/api/work/v1/attendance/flow/web/flowlong', {
                    method: 'POST',
                    data: {
                        attendanceFlowType: 'onBusiness',
                        organizationCode: currentUser.currentOrgCode,
                        startTime: postStartTime,
                        endTime: postEndTime,
                        flowTimeUnit: unit,
                        ...extra
                    }
                });

                if (result.code === 10000) {
                    form.setFieldsValue({
                        duration: {
                            durationText: getDurationFlexible(result.data, 2),
                            duration: result.data.durationLong
                        }
                    });
                } else {
                    form.setFields({
                        duration: {
                            value: 0,
                            errors: [new Error(result.msg)]
                        }
                    });
                }
            }
        } else {
            form.setFieldsValue({ duration: '' });
        }
    };

    // 监听表单
    const handleChanged = (value, formId) => {
        const timeControlList = ['startTime', 'endTime'];
        const expenseControlList = ['hotelExpense', 'transportExpense', 'businessTripAllowance', 'otherExpense'];

        if (expenseControlList.includes(formId)) {
            const fieldsValue = form.getFieldsValue(expenseControlList);
            const obj = {};
            obj[formId] = value;
            setTotalExpense({ ...fieldsValue, ...obj });
        }

        if (timeControlList.includes(formId)) {
            const fieldsValue = form.getFieldsValue(timeControlList);
            const obj = {};
            obj[formId] = value;
            setDuration({ ...fieldsValue, ...obj });
        }
    };

    return (
        Array.isArray(list) &&
        list.map(item => {
            const { label, formId, initialValue, extra } = item;
            const rules = resolveFormRules(item);
            if (formId === 'businessTripTotalExpense') {
                item.options = {
                    ...item.options,
                    disabled: true
                };
            }
            if (formId === 'duration') {
                item.options = { ...item.options, display: true };
            }
            return (
                <Form.Item label={label} key={formId} extra={extra}>
                    {getFieldDecorator(formId, {
                        initialValue: formId === 'businessTripTotalExpense' && !initialValue ? undefined : initialValue,
                        rules
                    })(
                        <AutoRenderComponent
                            form={form}
                            config={item}
                            onChange={value => handleChanged(value, formId)}
                        />
                    )}
                </Form.Item>
            );
        })
    );
};

export default BusinessTrip;
